float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 Inverse;

float4 light_pos;
float4 emissive;
float4 ambient;
float4 diffuse;
float4 specular;
int shininess;

float3 eye_pos;

float4 specularMaterial;

Texture colorTexture;

sampler colorTextureSampler = sampler_state
{
    texture = <colorTexture>;	
	magfilter = LINEAR;
	minfilter = LINEAR; 
	mipfilter = LINEAR;
	AddressU = clamp; // wrap; // mirror;
	AddressV = clamp; 
};


struct VertexShaderInput
{
    float4 Position : POSITION0;
	float4 Normal : NORMAL0;
	float2 textureCoord : TEXCOORD0;
};


struct VertexShaderOutput
{
    float4 Position : POSITION0;
	float2 textureCoord : TEXCOORD0;
	float4 Normal : TEXCOORD1;
	float4 worldPosition : TEXCOORD2; 
};


VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;
	
    output.worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(output.worldPosition, View);
    output.Position = mul(viewPosition, Projection);

	output.textureCoord = input.textureCoord;

	output.Normal = mul(input.Normal, Inverse);

    return output;
}


float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    float3 L = normalize(light_pos.xyz - input.worldPosition.xyz);
    
    float3 N = normalize(input.Normal);
    
    float angleDiffuse = dot(L, N);
    
    float4 albedo = tex2D(colorTextureSampler, input.textureCoord);
    
    float3 V = normalize(eye_pos - input.worldPosition);
    
    float3 H = normalize(L + V);
    
    float angleSpecular = dot(N, H);
    
    float4 specularContribution = angleDiffuse > 0 
	? pow(max(angleSpecular, 0), shininess) * specularMaterial : 0;
    
    float4 output = emissive +
	 ambient * albedo +
	  max(angleDiffuse, 0) * albedo * diffuse +
	   specularContribution;

    return output;
}


technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
